package com.jie.server.mvc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jie.server.core.ServerApplication;
import com.jie.server.core.entity.ChannelAttachment;
import com.jie.server.core.entity.SessionNode;
import com.jie.server.mvc.mapper.UserMapper;
import com.jie.server.mvc.model.entity.User;
import com.jie.server.mvc.model.vo.UserUpdateVo;
import com.jie.server.mvc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author XieZhiJie
 * @since 2022-04-24
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;

    @Autowired
    public UserServiceImpl(
            UserMapper userMapper
    ) {
        this.userMapper = userMapper;
    }

    @Override
    public boolean register(User user) {
        // 判空处理
        if (user.getUserAccount() == null || user.getUserPassword() == null || user.getUsername() == null) {
            return false;
        }
        user.setUserAccount(user.getUserAccount().trim());
        user.setUserPassword(user.getUserPassword().trim());
        user.setUsername(user.getUsername().trim());
        String empty = "";
        if (empty.equals(user.getUserAccount()) || empty.equals(user.getUserPassword()) || empty.equals(user.getUsername())) {
            return false;
        }
        user.setUserId(null);

        // 查询是否存在当前用户
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_account", user.getUserAccount());
        if (this.userMapper.selectOne(userQueryWrapper) != null) {
            return false;
        }

        // 插入
        return this.userMapper.insert(user) > 0;
    }

    @Override
    public Integer login(User user) {
        if (user.getUserAccount() == null || user.getUserPassword() == null) {
            return null;
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_account", user.getUserAccount());
        User originalUser = this.userMapper.selectOne(userQueryWrapper);
        if (originalUser == null) {
            return null;
        }
        if (user.getUserPassword() != null && user.getUserPassword().equals(originalUser.getUserPassword())) {
            if (ServerApplication.SESSION.get(originalUser.getUserId()) != null) {
                // 已登录, 因此不允许再登录
                return -1;
            }
            try {
                // 初始化用户的登录信息并设置session
                SelectionKey key = ServerApplication.SELECTION_KEY_THREAD_LOCAL.get();
                ((ChannelAttachment) key.attachment()).id = originalUser.getUserId();
                SocketChannel socketChannel = (SocketChannel) key.channel();
                InetSocketAddress remoteAddress = (InetSocketAddress) socketChannel.getRemoteAddress();
                String address = remoteAddress.getAddress().getHostAddress();
                int port = remoteAddress.getPort();
                SessionNode sessionNode = new SessionNode(address, port, key);
                ServerApplication.SESSION.put(originalUser.getUserId(), sessionNode);
            } catch (Exception e) {
                return null;
            }
            return originalUser.getUserId();
        }
        return null;
    }

    @Override
    public List<User> getOnlineUserList() {
        List<Integer> onlineUserIds = new LinkedList<>();
        for (Map.Entry<Integer, SessionNode> entry : ServerApplication.SESSION.entrySet()) {
            onlineUserIds.add(entry.getKey());
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.select("user_id", "user_account", "username");
        userQueryWrapper.in("user_id", onlineUserIds);
        return this.userMapper.selectList(userQueryWrapper);
    }

    @Override
    public boolean update(Integer userId, UserUpdateVo userUpdateVo) {
        String empty = "";
        boolean canNotUpdate = (userUpdateVo.getUsername() == null || empty.equals(userUpdateVo.getUsername().trim())) && (userUpdateVo.getUserPassword() == null || empty.equals(userUpdateVo.getUserPassword().trim()));
        if (canNotUpdate) {
            return false;
        }
        User user = new User();
        user.setUserId(userId);
        user.setUserPassword(userUpdateVo.getUserPassword());
        user.setUsername(userUpdateVo.getUsername());
        return this.userMapper.updateById(user) > 0;
    }

}
